// 投票类型
import {type Timestamp, TS} from "./Timestamp.ts";
import {unEscape} from "../utils/StrUtils.ts";

export enum VoteType {
    // 投票主题
    VOTE_TOPIC = 0,
    // 菠菜主题
    BET_TOPIC = 1,
    // 评分主题
    SCORE_TOPIC = 2,
    // 评分回复
    SCORE_REPLY = 3,
}

// 投票结果展示方式
export enum VoteResultShow {
    // 投票后查看结果
    AFTER_VOTE = 1,
    // 结束后查看结果
    AFTER_END = 2,
    // 即时(默认)
    IMMEDIATELY = -1,
}

export interface VoteData {
    // 类型
    type: VoteType
    // 最多选择个数（每组）
    maxSelect: number | undefined
    // 声望限制
    reputation: number | undefined
    // 结束时间
    end: Timestamp | undefined
    // 结果展示方式
    resultShow: VoteResultShow
    // 选项被选中的总次数 (计算得到)
    totalCount: number
    // 总参与人数
    total: number
    // 选项分组，可能只有一组
    options: VoteOption[]
    // 分组数量
    groupCount: number
    // 评分结果分布
    scoreResults: ScoreResult[]
    //  (菠菜)最小投注金额，(评分)下限
    min: number | undefined
    //  (菠菜)最大投注金额，(评分)上限
    max: number | undefined
    //  (菠菜)总投注金额
    totalMoney: number
    //  (菠菜)胜出id
    successId: number | undefined
    //  评分标题
    title: string | undefined
    //  评分值
    score: number | undefined
    //  总分值
    totalScore: number
}

export interface VoteOption {
    id: number,
    //标题
    label: string,
    //组序号
    groupIndex: number,
    //被选择次数
    count: number,
    //选中次数占比 (计算得到)
    countPer: number,
    //选中次数占比，百分制保留2位小数 (计算得到)
    countPerFixed: number,
    //(菠菜)金额
    money: number,
    //(菠菜)金额占比 (计算得到)
    moneyPer: number,
    //(菠菜)金额占比，百分制保留2位小数 (计算得到)
    moneyPerFixed: number,
}

export interface ScoreResult {
    score: number
    count: number
    countPer: number,
    countPerFixed: number,
}


export const buildVoteData = (text: string | undefined): VoteData | undefined => {
    if (!text) return undefined
    const type = (parseVoteNumber(text, 'type') || VoteType.VOTE_TOPIC) as VoteType
    const maxSelect = parseVoteNumber(text, 'max_select')
    const end = parseVoteNumber(text, 'end')
    const resultShow = (parseVoteNumber(text, 'opt') || VoteResultShow.IMMEDIATELY) as VoteResultShow
    const min = parseVoteNumber(text, 'min')
    const max = parseVoteNumber(text, 'max')
    const successId = parseVoteNumber(text, 'done')
    let title: string | undefined = undefined
    let score: number | undefined = undefined
    let totalScore = 0
    let total = 0
    let totalCount = 0
    let totalMoney = 0

    const privValue = /priv~r\d+_(-*\d+)/.exec(text)?.[1]
    const reputation = privValue ? Number(privValue) : undefined
    const options: VoteOption[] = []
    const scoreResults: ScoreResult[] = []

    let groupIndex = 0
    const lines = text.split('~');
    for (let i = 0; i < lines.length; i += 2) {
        const key = lines[i]
        const value = lines[i + 1]
        const keyNumber = Number(key)
        const valueNumber = Number(value)
        // 选项统计结果的ID
        const optionResultId = Number(/_(\d+)/.exec(key)?.[1] || '0')

        // 如果key为数字
        if (!isNaN(keyNumber)) {
            switch (type) {
                case VoteType.SCORE_TOPIC:
                    title = value
                    break;
                case VoteType.SCORE_REPLY:
                    score = valueNumber
                    break;
                case VoteType.BET_TOPIC:
                case VoteType.VOTE_TOPIC: {
                    if (value === '===') {
                        groupIndex++
                    } else {
                        if (groupIndex === 0) groupIndex = 1
                        //添加选项
                        options.push({
                            id: keyNumber,
                            label: unEscape(value) || "",
                            groupIndex,
                            count: 0,
                            countPer: 0,
                            countPerFixed: 0,
                            money: 0,
                            moneyPer: 0,
                            moneyPerFixed: 0
                        })
                    }
                    break;
                }
            }
        }

        // 统计结果计算
        if (optionResultId) {
            const values = value.split(",").map(Number)
            total = values[2] || total
            if (type === VoteType.SCORE_TOPIC) {
                totalScore = values[1]
            } else {
                // 投票和菠菜，为选项填充人数和铜币数
                const op = options.find(i => i.id === optionResultId);
                if (op) {
                    op.count = values[0]
                    op.money = values[1]
                    totalCount += op.count
                    totalMoney += op.money
                }
            }
        }

        // 评分结果
        const scoreValue = /\d+s(\d+)/.exec(key)?.[1];
        const scoreN = scoreValue ? Number(scoreValue) : undefined
        if (scoreN) {
            scoreResults.push({score: scoreN, count: valueNumber, countPer: 0, countPerFixed: 0})
        }
    }

    // 评分结果排序
    scoreResults.sort((a, b) => b.score - a.score)
    scoreResults.forEach(it => {
        it.countPer = total === 0 ? 0 : it.count / total
        it.countPerFixed = Number((it.countPer * 100).toFixed(2))
    })

    //  按groupIndex分组计算选项的占比
    for (let i = 1; i < groupIndex + 1; i++) {
        // 分组
        const group = options.filter(it => it.groupIndex === i);
        const tc = group.map(it => it.count).reduce((a, b) => a + b, 0);
        const tm = group.map(it => it.money).reduce((a, b) => a + b, 0);
        group.forEach(it => {
            it.countPer = tc === 0 ? 0 : it.count / tc
            it.countPerFixed = Number((it.countPer * 100).toFixed(2))
            it.moneyPer = tm === 0 ? 0 : it.money / tm
            it.moneyPerFixed = Number((it.moneyPer * 100).toFixed(2))
        })
    }

    const res = {
        type, maxSelect, resultShow, end: TS(end), min, max, successId, reputation, options, total,
        totalCount, title, score, totalScore, totalMoney, scoreResults, groupCount: groupIndex,
    }
    console.debug('投票数据', res)
    return res
}


const parseVoteNumber = (text: string, prefix: string): number | undefined => {
    const regExp = new RegExp(`${prefix}~(\\d+)`)
    const value = regExp.exec(text)?.[1]
    return value ? Number(value) : undefined
}